package fr.skolian.core.command {
	import fr.skolian.core.interfaces.ICommand;

/*Skolian - Content management system for primary school - Copyright (c) 2011 - Olivier Gianotti - This file is part of Skolian. Skolian is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Skolian is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Skolian.  If not, see <http://www.gnu.org/licenses/>.
contact : ogianotti@gmail.com 

Skolian - Application de gestion de contenus pédagogiques en école primaire. Copyright (C) 2011 - Olivier Gianotti - Ce fichier est une partie de Skolian. Skolian est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier au titre des clauses de la Licence Publique Générale GNU, telle que publiée par la Free Software Foundation ; soit la version 2 de la Licence, ou (à votre discrétion) une version ultérieure quelconque. Ce programme est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE ; sans même une garantie implicite de COMMERCIABILITE ou DE CONFORMITE A UNE UTILISATION PARTICULIERE. Voir la Licence Publique Générale GNU pour plus de détails. Vous devriez avoir reçu un exemplaire de la Licence Publique Générale GNU avec ce programme ; si ce n'est pas le cas, consultez <http://www.gnu.org/licenses/>.
contact : ogianotti@gmail.com 
*/

public class MacroCommand extends AbstractCommand implements ICommand {

		private var isSequential:Boolean;		private var stopOnError:Boolean;
		private var commands:Array;
		
		private var executed:uint;
		
		public function MacroCommand(isSequential:Boolean = false, stopOnError:Boolean = true) {
			this.isSequential = isSequential;			this.stopOnError = stopOnError;
			executed = 0;
			commands = [];
			super();
		}
		
		public function addCommand(command:ICommand):void {
			commands.push(command);
		}
		
		public function execute():void {
			if (commands.length < 1) {
				dispatchEvent(new CommandEvent(CommandEvent.COMPLETE));
			} else {
				if (isSequential) {
					ICommand(commands[0]).addCompleteListener(onCommandComplete);
					ICommand(commands[0]).addErrorListener(onError);					ICommand(commands[0]).execute();
				} else {
					for (var i : Number = 0;i < commands.length; i++) {
						ICommand(commands[i]).addCompleteListener(onCommandComplete);
						ICommand(commands[i]).addErrorListener(onError);
						ICommand(commands[i]).execute();
					}
				}
				addEventListener(CommandEvent.COMPLETE, onAllComplete);
			}
		}
		
		public function get totalCommands():int {
			return commands.length;
		}

		protected function onCommandComplete(e:CommandEvent):void {
			if (e && e.target && ICommand(e.target)) {
				ICommand(e.target).removeCompleteListener(onCommandComplete);
				ICommand(e.target).removeErrorListener(onError);
			}
			executed++;
			
			if (executed == commands.length) {
				dispatchEvent(new CommandEvent(CommandEvent.COMPLETE));
			} else if (isSequential) {
				ICommand(commands[executed]).addCompleteListener(onCommandComplete);
				ICommand(commands[executed]).addErrorListener(onError);
				ICommand(commands[executed]).execute();
			}
		}

		protected function onAllComplete(e:CommandEvent):void {
			executed = 0;
		}

		protected function onError(e:CommandEvent):void {
			dispatchEvent(new CommandEvent(CommandEvent.ERROR));
			if (!stopOnError) {
				onCommandComplete(null);
			}
		}
		
		override public function clear():void{
			for (var i : Number = 0;i < commands.length; i++) {
				var command:ICommand = commands[i] as ICommand;
				if(!command)continue;
				command.removeCompleteListener(onCommandComplete);
				command.removeErrorListener(onError);
				command.clear();
				commands[i] = null;
			}
		}
	}
}
